package com.example.port.service.impl;

import com.example.port.entity.Cargo;
import com.example.port.entity.PortArea;
import com.example.port.entity.StorageRecord;
import com.example.port.mapper.CargoMapper;
import com.example.port.service.CargoService;
import com.example.port.service.PortAreaService;
import com.example.port.service.StorageRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class CargoServiceImpl implements CargoService {
    
    private final CargoMapper cargoMapper;
    private final PortAreaService portAreaService;
    private final StorageRecordService storageRecordService;
    
    @Autowired
    public CargoServiceImpl(CargoMapper cargoMapper, PortAreaService portAreaService, StorageRecordService storageRecordService) {
        this.cargoMapper = cargoMapper;
        this.portAreaService = portAreaService;
        this.storageRecordService = storageRecordService;
    }
    
    @Override
    @Transactional
    public int insertCargo(Cargo cargo) {
        // 设置默认状态为"在库"
        if (cargo.getStatus() == null) {
            cargo.setStatus("IN_STORAGE");
        }
        
        // 检查是否已设置ID，如果没有，则自动生成ID
        if (cargo.getCargoId() == null) {
            Integer maxId = cargoMapper.getMaxCargoId();
            cargo.setCargoId(maxId + 1);
        }
        
        int result = cargoMapper.insert(cargo);
        
        if (result > 0 && cargo.getEntryAreaId() != null && cargo.getWeight() != null) {
            // 更新港口区域使用容量
            updatePortAreaUsage(cargo.getEntryAreaId(), cargo.getWeight(), true);
            
            // 自动创建仓储记录
            createStorageRecord(cargo);
        }
        
        return result;
    }
    
    @Override
    public List<Cargo> getAllCargos() {
        // 默认只返回在库的货物
        return cargoMapper.selectByStatus("IN_STORAGE");
    }
    
    /**
     * 获取所有货物，包括已出库的
     * @return 所有货物列表
     */
    public List<Cargo> getAllCargosIncludingExited() {
        return cargoMapper.selectAll();
    }
    
    @Override
    public Cargo getCargoById(Integer cargoId) {
        return cargoMapper.selectById(cargoId);
    }
    
    @Override
    @Transactional
    public int updateCargo(Cargo cargo) {
        // 获取原货物信息
        Cargo oldCargo = cargoMapper.selectById(cargo.getCargoId());
        if (oldCargo == null) {
            return 0;
        }
        
        // 如果区域或重量变更，需要更新区域使用量
        boolean areaChanged = (oldCargo.getEntryAreaId() == null && cargo.getEntryAreaId() != null) || 
                             (oldCargo.getEntryAreaId() != null && cargo.getEntryAreaId() == null) ||
                             (oldCargo.getEntryAreaId() != null && cargo.getEntryAreaId() != null && 
                              !oldCargo.getEntryAreaId().equals(cargo.getEntryAreaId()));
                              
        boolean weightChanged = (oldCargo.getWeight() == null && cargo.getWeight() != null) ||
                               (oldCargo.getWeight() != null && cargo.getWeight() == null) ||
                               (oldCargo.getWeight() != null && cargo.getWeight() != null && 
                                oldCargo.getWeight().compareTo(cargo.getWeight()) != 0);
        
        if (areaChanged || weightChanged) {
            // 减去原区域使用量
            if (oldCargo.getEntryAreaId() != null && oldCargo.getWeight() != null) {
                updatePortAreaUsage(oldCargo.getEntryAreaId(), oldCargo.getWeight(), false);
            }
            
            // 增加新区域使用量
            if (cargo.getEntryAreaId() != null && cargo.getWeight() != null) {
                updatePortAreaUsage(cargo.getEntryAreaId(), cargo.getWeight(), true);
            }
        }
        
        return cargoMapper.update(cargo);
    }
    
    @Override
    @Transactional
    public int deleteCargo(Integer cargoId) {
        // 获取货物信息
        Cargo cargo = cargoMapper.selectById(cargoId);
        if (cargo == null) {
            return 0;
        }
        
        try {
            // 删除相关的仓储记录
            int recordsDeleted = storageRecordService.deleteStorageRecordsByCargoId(cargoId);
            System.out.println("删除货物 " + cargoId + " 相关的仓储记录: " + recordsDeleted + " 条");
            
            // 减去区域使用量
            if (cargo.getEntryAreaId() != null && cargo.getWeight() != null) {
                updatePortAreaUsage(cargo.getEntryAreaId(), cargo.getWeight(), false);
            }
            
            // 删除货物
            return cargoMapper.delete(cargoId);
        } catch (Exception e) {
            System.err.println("删除货物失败: " + e.getMessage());
            e.printStackTrace();
            throw e; // 抛出异常以触发事务回滚
        }
    }
    
    @Override
    public List<Cargo> getCargosByOwnerId(Integer ownerId) {
        return cargoMapper.selectByOwnerId(ownerId);
    }
    
    /**
     * 实现货物出库
     * 1. 更新相关仓储记录的实际出库时间和备注
     * 2. 减少港口区域的使用容量
     * 3. 将货物状态更新为"已出库"
     */
    @Override
    @Transactional
    public int exitCargo(Integer cargoId, Date actualExitTime, String operatorName, String exitNotes) {
        // 获取货物信息
        Cargo cargo = cargoMapper.selectById(cargoId);
        if (cargo == null) {
            return 0;
        }
        
        try {
            // 1. 查找该货物的仓储记录
            List<StorageRecord> records = storageRecordService.getStorageRecordsByCargoId(cargoId);
            if (records != null && !records.isEmpty()) {
                // 找到最新的一条仓储记录（通常只有一条）
                StorageRecord latestRecord = records.get(0);
                
                // 更新仓储记录为已出库
                latestRecord.setActualExitTime(actualExitTime);
                latestRecord.setOperatorName(operatorName);
                latestRecord.setNotes((latestRecord.getNotes() != null ? latestRecord.getNotes() + " | " : "") + 
                                     "出库备注: " + exitNotes);
                latestRecord.setLastUpdated(new Date());
                
                // 保存更新后的仓储记录
                storageRecordService.updateStorageRecord(latestRecord);
                System.out.println("更新仓储记录 " + latestRecord.getRecordId() + " 为已出库状态");
            }
            
            // 2. 减少港口区域的使用容量
            if (cargo.getEntryAreaId() != null && cargo.getWeight() != null) {
                updatePortAreaUsage(cargo.getEntryAreaId(), cargo.getWeight(), false);
                System.out.println("减少港口区域 " + cargo.getEntryAreaId() + " 的使用容量: " + cargo.getWeight());
            }
            
            // 3. 更新货物状态为已出库，而不是删除
            cargo.setStatus("EXITED");
            int result = cargoMapper.update(cargo);
            System.out.println("货物 " + cargoId + " 状态更新为已出库: " + (result > 0 ? "成功" : "失败"));
            
            return result;
        } catch (Exception e) {
            System.err.println("货物出库处理失败: " + e.getMessage());
            e.printStackTrace();
            throw e; // 抛出异常以触发事务回滚
        }
    }
    
    /**
     * 更新港口区域使用容量
     * @param areaId 区域ID
     * @param weight 货物重量
     * @param isAdd 是否增加使用量
     */
    private void updatePortAreaUsage(Integer areaId, BigDecimal weight, boolean isAdd) {
        if (areaId == null || weight == null) {
            return;
        }
        
        PortArea portArea = portAreaService.getPortAreaById(areaId);
        if (portArea == null) {
            return;
        }
        
        BigDecimal currentUsage = portArea.getCurrentUsage();
        if (currentUsage == null) {
            currentUsage = BigDecimal.ZERO;
        }
        
        BigDecimal newUsage;
        if (isAdd) {
            newUsage = currentUsage.add(weight);
        } else {
            newUsage = currentUsage.subtract(weight);
            if (newUsage.compareTo(BigDecimal.ZERO) < 0) {
                newUsage = BigDecimal.ZERO;
            }
        }
        
        // 使用BigDecimal的doubleValue方法获取double值
        portAreaService.updatePortAreaUsage(areaId, newUsage.doubleValue());
        
        // 打印日志，便于调试
        System.out.println("更新港口区域 " + areaId + " 使用量: " + 
                          (isAdd ? "+" : "-") + weight + 
                          ", 原使用量: " + currentUsage + 
                          ", 新使用量: " + newUsage);
    }
    
    /**
     * 为新增的货物创建仓储记录
     * @param cargo 新增的货物
     */
    private void createStorageRecord(Cargo cargo) {
        try {
            StorageRecord record = new StorageRecord();
            record.setCargoId(cargo.getCargoId());
            record.setAreaId(cargo.getEntryAreaId());
            
            // 设置入库时间为当前时间
            Date now = new Date();
            record.setEntryTime(now);
            
            // 设置预计离库时间为30天后
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.add(Calendar.DAY_OF_MONTH, 30);
            record.setExpectedExitTime(calendar.getTime());
            
            // 设置操作员为系统自动
            record.setOperatorName("系统自动");
            
            // 设置备注
            record.setNotes("货物入库自动创建记录");
            
            // 插入记录
            int result = storageRecordService.insertStorageRecord(record);
            
            // 打印日志
            System.out.println("为货物 " + cargo.getCargoId() + " 自动创建仓储记录: " + 
                              (result > 0 ? "成功" : "失败"));
        } catch (Exception e) {
            System.err.println("创建仓储记录失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 根据状态获取货物
     * @param status 货物状态
     * @return 指定状态的货物列表
     */
    @Override
    public List<Cargo> getCargosByStatus(String status) {
        return cargoMapper.selectByStatus(status);
    }
} 
